﻿using System;
using System.Diagnostics;
using System.Reflection;

namespace Tequila.Phone.Infrastructure.Logging
{
    internal sealed class DefaultLogger : ILogger
    {
        private const string Template = "[{0:yyyy-MM-dd hh-mm-ss.ffff}]{1,-7}[{2}] - {3}";

        private readonly string _type = "EMPTY";

        internal DefaultLogger(string type)
        {
            if (!string.IsNullOrWhiteSpace(type))
            {
                _type = type;
            }
        }

        internal DefaultLogger(MemberInfo type)
        {
            if (type != null)
            {
                _type = type.Name;
            }
        }

        private static string CreateLevelPattern(Level level)
        {
            return string.Format("[{0}]", Enum.GetName(typeof (Level), level).ToUpperInvariant());
        }

        #region Implementation of ILogger
        
        /// <summary>
        /// Determines whether provided <see cref="Level"/> is enabled.
        /// </summary>
        /// <param name="level"><see cref="Level"/></param>
        /// <returns></returns>
        public bool IsEnabled(Level level)
        {
#if DEBUG
            return true;
#else
            return false;
#endif
        }

        /// <summary>
        /// Writes logger entry.
        /// </summary>
        /// <param name="level"><see cref="Level"/></param>
        /// <param name="message">Message to be written.</param>
        public void Write(Level level, string message)
        {
            if (!IsEnabled(level))
            {
                return;
            }

            Debug.WriteLine(Template, DateTime.Now, CreateLevelPattern(level), _type, message);
        }

        /// <summary>
        /// Writes logger entry.
        /// </summary>
        /// <param name="level"><see cref="Level"/></param>
        /// <param name="format">Message format to be used</param>
        /// <param name="args">Parameters</param>
        public void Write(Level level, string format, params object[] args)
        {
            if (!IsEnabled(level))
            {
                return;
            }

            string msg;

            try
            {
                msg = string.Format(format, args);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(Template,
                                DateTime.Now,
                                CreateLevelPattern(Level.Error),
                                _type,
                                MethodBase.GetCurrentMethod());

                Debug.WriteLine(ex);

                msg = string.Empty;
            }

            Write(level, msg);
        }

        /// <summary>
        /// Writes logger entry.
        /// </summary>
        /// <param name="level"><see cref="Level"/></param>
        /// <param name="exception">Exception to be logged.</param>
        public void Write(Level level, Exception exception)
        {
            Write(level, string.Empty, exception);
        }

        /// <summary>
        /// Writes logger entry.
        /// </summary>
        /// <param name="level"><see cref="Level"/></param>
        /// <param name="message">Message to be written.</param>
        /// <param name="exception">Exception to be logged.</param>
        public void Write(Level level, string message, Exception exception)
        {
            if (!IsEnabled(level))
            {
                return;
            }

            Debug.WriteLine(Template, DateTime.Now, CreateLevelPattern(level), _type,
                            string.IsNullOrWhiteSpace(message) ? string.Empty : message);
            Debug.WriteLine(exception);
        }

        #endregion
    }
}